package com.fili.core.serial;

import com.fili.core.Log;
import gnu.io.*;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Enumeration;
import java.util.Random;
import java.util.TooManyListenersException;


/**
 * Created by Claudiu-Florin FILIMON
 * Date: Oct 19, 2006
 * Time: 10:39:12 PM
 */
public class SerialReader implements SerialPortEventListener
{
    private SerialParser serialParser;
    private boolean portOpened;

    private SerialPort sPort;

    private Timer timer;
    private BufferedReader inputSerial;


    public SerialReader(SerialParser serialParser)
    {
        this.serialParser = serialParser;

        timer = new Timer(1000, new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                Random r = new Random();
                String s = "";
                while (r.nextInt(10) > 2)
                {
                    if (r.nextInt(10) > 6)
                        s += ":";
                    s += (char) ('a' + r.nextInt(20));
                }

                if (r.nextInt(10) > 5)
                {
                    int c = r.nextInt(8);
                    int v = r.nextInt(1000) + 1000;
                    if (r.nextInt(5) > 3)
                        v = 3000;
                    if (r.nextInt(10) > 5)
                        c += 8;
                    s += ":" + ((char) ('0' + c)) + ";" + v + " 0100";
                }
                while (r.nextInt(10) > 2)
                {
                    if (r.nextInt(10) > 6)
                        s += ":";
                    s += (char) ('a' + r.nextInt(20));
                }
                onReceiveData(s);
            }
        });
        timer.start();
    }

    public boolean openPort(String port)
    {
        closePort();

        Enumeration portId = CommPortIdentifier.getPortIdentifiers();
        CommPortIdentifier spid = null;

        while (portId.hasMoreElements())
        {
            CommPortIdentifier pid = (CommPortIdentifier) portId.nextElement();
            if (pid.getName().equals(port))
                spid = pid;
        }

        if (spid == null)
            return false;

        try
        {
            sPort = (SerialPort) spid.open("JDry", 10000);
        }
        catch (PortInUseException e)
        {
            Log.writeLog(e);
            return false;
        }

        try
        {
            sPort.setSerialPortParams(2400, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
        }
        catch (UnsupportedCommOperationException e)
        {
            sPort.close();
            Log.writeLog(e);
            return false;
        }

        sPort.notifyOnDataAvailable(true);

        try
        {
            sPort.addEventListener(this);
        }
        catch (TooManyListenersException e)
        {
            sPort.close();
            Log.writeLog(e);
            return false;
        }

        try
        {
            inputSerial = new BufferedReader(new InputStreamReader(sPort.getInputStream()));
        }
        catch (IOException e)
        {
            sPort.close();
            Log.writeLog(e);
            return false;
        }

        portOpened = true;
        return true;
    }

    public boolean closePort()
    {
        if (portOpened)
        {
            sPort.close();
            portOpened = false;
        }
        return true;
    }

    public void onReceiveData(String data)
    {
        if (serialParser != null)
            serialParser.receiveData(data);
        try
        {
            FileOutputStream fos = new FileOutputStream("data_nice.txt", true);
            fos.write((new Date().toString() + " >>>" + data + "<<<\n").getBytes());
            fos.close();

            fos = new FileOutputStream("data_raw.txt", true);
            fos.write(data.getBytes());
            fos.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void serialEvent(SerialPortEvent serialPortEvent)
    {
        try
        {
            String s = "";
            System.out.println();
            while (inputSerial.ready())
                s += (char) (inputSerial.read());
            onReceiveData(s);
        }
        catch (IOException e)
        {
            Log.writeLog(e);
        }
    }
}
